package epraxis.servlet.app.admin.usuario;

import entity.DatoUsuario;
import entity.DatoUsuarioPK;
import entity.Empresa;
import entity.TipoUsuario;
import entity.Usuario;
import entity.UsuarioCursoAsignado;
import enums.EnumModoOperacion;
import enums.EnumTipoUsuario;
import facade.EpraxisHome;
import java.io.IOException;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.ejb.EJB;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import utils.EpraxisUtils;

@WebServlet(name = "MantenedorUsuarioProcess", urlPatterns = {"/app/admin/usuario/MantenedorUsuarioProcess.do"})
public class MantenedorUsuarioProcess extends HttpServlet {

    @EJB
    private EpraxisHome home;

    private Usuario usuarioSesion;
    private EnumModoOperacion modo;

    private Usuario usuarioEditar;
    private TipoUsuario tipoUsuario;
    private String nombreUsuario;
    private String clave;
    private Empresa empresa;
    private String nombre;
    private String primerApellido;
    private String segundoApellido;
    private String rut;
    private String direccion;
    private String strFechaNacimiento;
    private String[] cursosAsignados;
    private Date fechaNacimiento;

    protected void processRequest(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        response.setContentType("text/html;charset=UTF-8");

        try {
            modo = EnumModoOperacion.valueOf(request.getParameter("modo"));
        } catch (Exception e) {
            throw new IOException("El modo de operación no es valido");
        }

        usuarioSesion = (Usuario) request.getSession().getAttribute("__usuarioSesion");
        if (usuarioSesion == null) {
            throw new ServletException("Debe iniciar sesión con su cuenta de administrador para administrar usuarios");
        }

        nombreUsuario = request.getParameter("nombreUsuario");
        clave = request.getParameter("clave");
        empresa = usuarioSesion.getEmpresa();
        nombre = request.getParameter("nombre");
        primerApellido = request.getParameter("primerApellido");
        segundoApellido = request.getParameter("segundoApellido");
        rut = request.getParameter("rut");
        direccion = request.getParameter("direccion");
        strFechaNacimiento = request.getParameter("fechaNacimiento");
        cursosAsignados = request.getParameterValues("cursoAsignado");

        try {
            EnumTipoUsuario enumTipoUsuario = EnumTipoUsuario.getTipoUsuarioByID(Integer.parseInt(request.getParameter("tipoUsuario")));
            tipoUsuario = home.getTipoUsuarioByID(enumTipoUsuario.getId());
            System.out.println("tipoUsuario = " + tipoUsuario);
            if (tipoUsuario == null) {
                throw new ServletException("El tipo de usuario no es válido");
            }
        } catch (Exception e) {
            throw new ServletException("No ha especificado el tipo de usuario o no es válido");
        }

        if (nombreUsuario == null || nombreUsuario.isEmpty()) {
            throw new ServletException("Debe ingresar un nombre de usuario válido");
        }
        if (modo.isInsert()) {
            if (clave == null || clave.isEmpty()) {
                throw new ServletException("Debe ingresar una clave válida");
            }
            if (clave.length() < 6) {
                throw new ServletException("La clave es demasiado corta, elija una con al menos 6 caracteres");
            }
        }
        if (empresa == null) {
            throw new ServletException("La empresa del usuario administrador no es válida");
        }
        if (modo.isInsert()) {
            if (!EpraxisUtils.validarRut(rut)) {
                throw new ServletException("El RUT no es válido");
            }
        }
        if (strFechaNacimiento != null && !strFechaNacimiento.isEmpty()) {
            DateFormat format = new SimpleDateFormat("yyyy-MM-dd");
            try {
                fechaNacimiento = format.parse(strFechaNacimiento);
            } catch (ParseException ex) {
                Logger.getLogger(MantenedorUsuarioProcess.class.getName()).log(Level.SEVERE, null, ex);
                throw new ServletException("La fecha de nacimiento no es válida");
            }
        }

        if (modo.isInsert()) {
            Usuario usuarioNuevo;
            try {
                usuarioNuevo = new Usuario();
                usuarioNuevo.setActivo("S");
                usuarioNuevo.setClave(clave);
                usuarioNuevo.setEmpresa(empresa);
                usuarioNuevo.setFechaRegistro(new Date());
                usuarioNuevo.setUsuario(nombreUsuario);
                usuarioNuevo.setTipoUsuarioList(new ArrayList<TipoUsuario>());
                usuarioNuevo.getTipoUsuarioList().add(tipoUsuario);

                if (cursosAsignados != null && cursosAsignados.length > 0) {
                    List<UsuarioCursoAsignado> listaCursoAsignado = new ArrayList<UsuarioCursoAsignado>();
                    for (String cursoAsignado : cursosAsignados) {
                        try {
                            UsuarioCursoAsignado nuevoCursoAsignado = new UsuarioCursoAsignado();
                            nuevoCursoAsignado.setCurso(home.getCursoByID(Integer.parseInt(cursoAsignado)));
                            nuevoCursoAsignado.setUsuario(usuarioNuevo);
                            listaCursoAsignado.add(nuevoCursoAsignado);
                        } catch (Exception e) {
                            throw new ServletException("Ha ocurrido un error al asignar los cursos");
                        }
                    }
                    usuarioNuevo.setUsuarioCursoAsignadoList(listaCursoAsignado);
                }
            } catch (Exception e) {
                throw new ServletException("No se ha podido crear el usuario");
            }

//              home.createUsuario(usuarioNuevo);
            DatoUsuario datoUsuario;
            try {
                datoUsuario = new DatoUsuario();
                DatoUsuarioPK pk = new DatoUsuarioPK();
                pk.setRut(Integer.parseInt(rut.substring(0, rut.length() - 2)));
                datoUsuario.setDatoUsuarioPK(pk);
                datoUsuario.setDireccion(direccion);
                datoUsuario.setDv(String.valueOf(rut.charAt(rut.length() - 1)));
                datoUsuario.setFechaNacimiento(fechaNacimiento);
                datoUsuario.setNombre(nombre);
                datoUsuario.setPrimerApellido(primerApellido);
                datoUsuario.setSegundoApellido(segundoApellido);
                datoUsuario.setUsuario(usuarioNuevo);

                home.createDatoUsuario(datoUsuario);
            } catch (Exception e) {
                throw new ServletException("Ha ocurrido un error al crear los datos personales del usuario");
            }

            response.getWriter().write("Usuario creado correctamente");
        } else if (modo.isEdit()) {
            try {
                Integer idUsuarioEditar = new Integer(request.getParameter("id"));
                usuarioEditar = home.getUsuarioByID(idUsuarioEditar);
            } catch (Exception e) {
                throw new IOException("Debe especificar el usuario para editar");
            }

            try {
                home.removeTipoUsuarioFromUsuario(usuarioEditar);

                usuarioEditar = home.getUsuarioByID(usuarioEditar.getId());
                usuarioEditar.setActivo("S");
                usuarioEditar.setUsuario(nombreUsuario);

                home.createTipoUsuarioForUsuario(tipoUsuario, usuarioEditar);
                
                for (TipoUsuario tu : usuarioEditar.getTipoUsuarioList()) {
                    System.out.println("tu = " + tu.getNombre());
                }

                int filasEliminadas = home.removeCursosAsignadosUsuario(usuarioEditar);
                System.out.println("Se han eliminado " + filasEliminadas + " registros de CursoAsignados");

                if (cursosAsignados != null && cursosAsignados.length > 0) {
                    List<UsuarioCursoAsignado> listaCursoAsignado = new ArrayList<UsuarioCursoAsignado>();
                    for (String cursoAsignado : cursosAsignados) {
                        try {
                            UsuarioCursoAsignado nuevoCursoAsignado = new UsuarioCursoAsignado();
                            nuevoCursoAsignado.setCurso(home.getCursoByID(Integer.parseInt(cursoAsignado)));
                            nuevoCursoAsignado.setUsuario(usuarioEditar);
                            listaCursoAsignado.add(nuevoCursoAsignado);
                        } catch (Exception e) {
                            throw new ServletException("Ha ocurrido un error al asignar los cursos");
                        }
                    }
                    usuarioEditar.setUsuarioCursoAsignadoList(listaCursoAsignado);
                    home.editUsuario(usuarioEditar);
                }
            } catch (Exception e) {
                throw new ServletException("No se ha podido modificar el usuario");
            }

            DatoUsuario datoUsuario = home.getDatoUsuarioByUsuario(usuarioEditar);
            try {
                datoUsuario.setDireccion(direccion);
                datoUsuario.setFechaNacimiento(fechaNacimiento);
                datoUsuario.setNombre(nombre);
                datoUsuario.setPrimerApellido(primerApellido);
                datoUsuario.setSegundoApellido(segundoApellido);

                home.editDatoUsuario(datoUsuario);
            } catch (Exception e) {
                throw new ServletException("Ha ocurrido un error al modificar los datos personales del usuario");
            }

            response.getWriter().write("Usuario " + (modo.isInsert() ? "creado" : "modificado") + " correctamente");
        }
    }

    // <editor-fold defaultstate="collapsed" desc="HttpServlet methods. Click on the + sign on the left to edit the code.">
    /**
     * Handles the HTTP <code>GET</code> method.
     *
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        processRequest(request, response);
    }

    /**
     * Handles the HTTP <code>POST</code> method.
     *
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        processRequest(request, response);
    }

    /**
     * Returns a short description of the servlet.
     *
     * @return a String containing servlet description
     */
    @Override
    public String getServletInfo() {
        return "Short description";
    }// </editor-fold>

}
